package com.hk.player;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;

import com.hk.player.core.DataCallback;
import com.hk.player.core.MonitorMediaData;
import com.hk.player.core.Protocol;
import com.hk.player.utils.AutoPlayUtils;
import com.zhoug.common.utils.LogUtils;
import com.zhoug.common.utils.StringUtils;
import com.zhoug.player.core.PlayListener;
import com.zhoug.player.core.VideoRecordListener;
import com.zhoug.player.core.ZPlayer;
import com.zhoug.player.exoplayer.ExoPlayerHelper;
import com.zhoug.player.hikvision.HikvisionPlayerHelper;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

/**
 * @author: zhoug
 * @since: 2025-08-04
 */
public class PlayerView extends AbsPlayerView {
    private static final String TAG = ">>>PlayerView";
    private static boolean debug = true;
    private ZPlayer mPlayer;
    public static final int ENGINE_EXO = 1;
    public static final int ENGINE_TX = 2;
    public static final int ENGINE_HIK = 3;
    private int mEngine = ENGINE_EXO;
    /**
     * 是否自动创建Player
     */
    private boolean autoCreatePlayer = true;

    private void configPlayerEngine() {
        mEngine = ENGINE_EXO;
    }


    public PlayerView(@NonNull Context context) {
        super(context);
    }

    public PlayerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public PlayerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public PlayerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

    }

    /**
     * 是否自动创建Player
     *
     * @param autoCreatePlayer ture:自动创建,false:需要外部设置
     */
    public void setAutoCreatePlayer(boolean autoCreatePlayer) {
        this.autoCreatePlayer = autoCreatePlayer;
    }

    public void setPlayer(ZPlayer player) {
        this.mPlayer = player;
        if(mPlayer!=null){
            initPlayer();
        }
    }

    public ZPlayer getPlayer() {
        return mPlayer;
    }

    @UnstableApi
    @Override
    protected void onViewCreated() {
        configPlayerEngine();

    }

    private void printPlayEngine() {
        switch (mEngine) {
            case ENGINE_TX:
                LogUtils.d(TAG, "initPlayer:腾讯播放器");
                break;
            case ENGINE_HIK:
                LogUtils.d(TAG, "initPlayer:海康播放器");
                break;
//            case ENGINE_VLC:
//                LogUtils.d(TAG, "initPlayer:LVC播放器");
//                break;
            default:
                mProtocol = Protocol.HLS;
                LogUtils.d(TAG, "initPlayer:ExoPlayer播放器");
                break;
        }
    }



    private ZPlayer createPlayer() {
        ZPlayer player;
        switch (mEngine) {
//            case ENGINE_TX:
//                mPlayer = new TXLivePlayerHelper(getContext());
//                mProtocol= FirmMonitor.PROTOCOL_HLS;
//                break;
            case ENGINE_HIK:
                player = new HikvisionPlayerHelper();
                mProtocol = Protocol.RTSP;
                break;
            default:
                player = crateExoPlayer();
                mProtocol = Protocol.HLS;
                break;
        }
        return player;
    }


    /**
     * 创建Exo播放器
     *
     * @return
     */
    @OptIn(markerClass = UnstableApi.class)
    private ExoPlayerHelper crateExoPlayer() {
        ExoPlayerHelper exoPlayerHelper = new ExoPlayerHelper(getContext());
        exoPlayerHelper.setDetectAccessUnits(true);
        exoPlayerHelper.setIgnoreAacStream(true);
        return exoPlayerHelper;
    }

    private void initPlayer() {
        if(autoCreatePlayer && mPlayer==null){
            mPlayer=createPlayer();
        }
        if(mPlayer==null){
            LogUtils.e(TAG, "initPlayer: player is null");
            return;
        }
        printPlayEngine();

        mPlayer.setVideoTextureView(getTextureView());
        getTextureView().setKeepScreenOn(true);//保持亮屏
        mPlayer.setRenderMode(ZPlayer.RENDER_MODE_FULL_FILL_SCREEN);
        setMute(mMute);//静音
        mPlayer.setPlayListener(mPlayListener);
        mPlayer.setCapturePictureListener(((success, path) -> {

        }));
        mPlayer.setVideoRecordListener(new VideoRecordListener() {
            @Override
            public void onStartRecordVideo() {
                LogUtils.d(TAG, "onStartRecordVideo:开始录像");
                if (onRecordVideoListener != null) {
                    onRecordVideoListener.onStart();
                }
            }

            @Override
            public void onStopRecordVideo(String path) {
                LogUtils.d(TAG, "onStopRecordVideo:path:" + path);
                if (onRecordVideoListener != null) {
                    onRecordVideoListener.onStop(path);
                }
            }

            @Override
            public void onErrorRecordVideo(String error) {
                if (onRecordVideoListener != null) {
                    onRecordVideoListener.onError(error);
                }
            }

            /**
             * 录像时间进度
             *
             * @param time
             */
            @Override
            public void onRecordVideoTime(int time) {

            }
        });
        mPlayer.setOnTalkListener(new com.zhoug.player.core.OnTalkListener() {
            @Override
            public void onTalkCallback(int status, String error) {
                if (onTalkListener != null) {
                    onTalkListener.onTalkCallback(status, error);
                }
            }
        });

        //电子放大
        PlayerWindowView playWindowView = getPlayWindowView();
        playWindowView.setZoomEnable(false);
        playWindowView.setOnDigitalZoomListener(new PlayerWindowView.OnDigitalZoomListener() {
            @Override
            public void onZoomListener(Rect oRect, Rect curRect) {
                if (mPlayer != null) {
                    LogUtils.d(TAG, "onZoomChange:oRect=" + oRect + ",curRect" + curRect);
                    mPlayer.openDigitalZoom(oRect, curRect);

                }
            }

            @Override
            public void onCloseDigital() {
                mPlayer.closeDigitalZoom();
            }
        });
    }

    private PlayListener mPlayListener = new PlayListener() {
        @Override
        public void onPlayStatusChange(@ZPlayer.State int state) {
            switch (state) {
                case ZPlayer.STATE_IDLE:
                    LogUtils.d(TAG, "onPlayStatusChange:空闲");
                    cancelPlayLoading();
                    setPlayButtonStatus(false);
                    break;
                case ZPlayer.STATE_START:
                    LogUtils.d(TAG, "onPlayStatusChange:开始");
                    hideError();
                    showPlayLoading();
                    setPlayButtonStatus(true);
                    break;
                case ZPlayer.STATE_PAUSE:
                    LogUtils.d(TAG, "onPlayStatusChange:暂停");
                    cancelPlayLoading();
                    setPlayButtonStatus(false);
                    break;
                case ZPlayer.STATE_PLAYING:
                    LogUtils.d(TAG, "onPlayStatusChange:播放成功");

                    hideError();
                    playSuccess();
                    captureCacheImageDelay();
                    break;
                case ZPlayer.STATE_ENDED:
                    LogUtils.d(TAG, "onPlayStatusChange:播放完成");
                    toast("播放完成");
                    cancelPlayLoading();
                    setPlayButtonStatus(false);
                    break;
            }

        }

        @Override
        public void onPlayError(int code, String error) {
            LogUtils.e(TAG, "code:" + code + ",error" + error);
            if (mRetryCount < RETRY_MAX_COUNT) {
//                toast("url失效,正在重新请求");
                mRetryCount++;
                LogUtils.e(TAG, "第" + mRetryCount + "次重新请求url:");
                getMonitorPlayUrl(mProtocol, new DataCallback<MonitorMediaData>() {
                    @Override
                    public void onSuccess(MonitorMediaData mediaData) {
                        mMediaData = mediaData;
                        _startPlay();
                    }

                    @Override
                    public void onFailure(String error) {
                        startPlayFail(error);
                    }
                });
            } else {
               /* if (code == PlayError.BAD_HTTP_STATUS) {
                    setOffLine();
                } else {
                    startPlayFail(error);
                }*/
                startPlayFail("视频加载失败");
                stopPlay();
            }


        }
    };


    @Override
    public void startPlay() {
        if (mPlayer == null) {
            initPlayer();
        }
        if (mPlayer == null) {
            LogUtils.e(TAG, "startPlay: player is null");
            return;
        }

         /*   if (isOffLine()) {
                LogUtils.d(TAG, "startPlay:离线,playUrl=" + playUrl);
                return;
            }*/
        //判断 url是否正确
        if (mMediaData == null) {
            LogUtils.e(TAG, "startPlay:mMediaData is null");
            return;
        }
        if (StringUtils.isNullOrEmpty(mMediaData.getRealPlayUrl())) {
            hideError();
            showPlayLoading();
            setPlayButtonStatus(true);
            getMonitorPlayUrl(mProtocol, new DataCallback<MonitorMediaData>() {
                @Override
                public void onSuccess(MonitorMediaData mediaData) {
                    mMediaData = mediaData;
                    startPlayWithRightUrl();
                }

                @Override
                public void onFailure(String error) {
                    startPlayFail(error);
                }
            });
        } else {
            startPlayWithRightUrl();
        }
    }

    @Override
    public void preload() {
        if (mPlayer == null) {
            initPlayer();
        }
        if (mPlayer == null) {
            LogUtils.e(TAG, "startPlay: player is null");
            return;
        }
        mPlayer.preLoad();

    }

    /**
     * playUrl正确时 开始播放
     */
    private void startPlayWithRightUrl() {
        try {
            if (mPlayer.isPlaying()) {
                LogUtils.d(TAG, "startPlay:正在播放");
                return;
            }
            int playSate = mPlayer.getPlaySate();
            if (playSate == ZPlayer.STATE_PAUSE||playSate == ZPlayer.STATE_PREPARED) {
                mPlayer.resumePlay();
                return;
            }
            hideError();
            showPlayLoading();
            setPlayButtonStatus(true);
            _startPlay();
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.e(TAG, "startPlay:" + e.getMessage());
            startPlayFail("发生错误");
        }
    }


    private void _startPlay() {
        if (mMediaData == null || StringUtils.isNullOrEmpty(mMediaData.getRealPlayUrl())) {
            startPlayFail("没有播放地址");
            return;
        }
        String realPlayUrl = mMediaData.getRealPlayUrl();
        printPlayEngine();
        LogUtils.d(TAG, "开始播放:" + realPlayUrl);
        mPlayer.setPlayUrl(realPlayUrl);
        mPlayer.startPlay();
        setMute(mMute);
    }

    /**
     * 播放失败
     *
     * @param error
     */
    private void startPlayFail(String error) {
        setPlayButtonStatus(false);
        setPlayButtonVisibility(true);
        showError(error);
        cancelPlayLoading();
    }

    /**
     * 播放成功
     */
    private void playSuccess() {
        //播放成功重置次数
        mRetryCount = 0;
        setMute(mMute);
        hideError();
        setVideoCoverImage(false);
        setPlayButtonStatus(true);
        setPlayButtonVisibility(false);
        cancelPlayLoading();
    }

    @Override
    protected void _stopPlay() {
        try {
            if (mPlayer != null) {
                LogUtils.d(TAG, "stopPlay:停止播放");
                mPlayer.stopPlay();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void pausePlay() {
        /*if (isOffLine()) {
            return;
        }*/
        cancelRequest();
        LogUtils.d(TAG, "pausePlay:暂停播放");
        cancelPlayLoading();
        setPlayButtonStatus(false);
        if (mPlayer != null) {
            try {
                mPlayer.pausePlay();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void releasePlayer() {
        super.releasePlayer();
        if(mPlayer!=null){
            LogUtils.d(TAG, "releasePlayer:释放播放器资源");
            mPlayer.release();
            mPlayer=null;
        }
    }

    /**
     * 开始回放
     *
     * @param startTime
     */
    @Override
    public void startPlayback(long startTime) {

    }

    /**
     * 设置回放时间点
     *
     * @param curTime
     */
    @Override
    public void seekTo(long curTime) {

    }

    private void _setMute(boolean mute) {
        if (mPlayer != null) {
            LogUtils.d(TAG, "setMute 静音 :" + mute);
            mPlayer.setMute(mute);//静音
        }
    }


    @Override
    public void setMute(boolean mute) {
       /* if (isOffLine()) {
            return;
        }*/
        if (mPlayer != null) {
            _setMute(mute);
            if(mute!=mMute){
                mMute = mute;
                if (onMuteChangeListener != null) {
                    onMuteChangeListener.onMuteChange(mMute);
                }
            }

        }

    }

    @Override
    public boolean isMute() {
        return mMute;
    }

    @Override
    public boolean isPlaying() {
        return mPlayer != null && mPlayer.isPlaying();
    }


    @Override
    public void startRecord(String path) {
        super.startRecord(path);

    }

    @Override
    public void stopRecord() {
        super.stopRecord();
    }




    public void startPlayWithMobileNetwork() {
        AutoPlayUtils.showMobileNetworkHint(getContext(), b -> {
            if (b) {
                startPlay();
            }
        });
    }





}
